import React from "react"
import { Redirect, withRouter } from "react-router-dom"
import request from '@/utils/request'
import store from '@/store'

export function withUser(InnerComponent) {
    return function OuterComponent(props) {
        let userInfo = localStorage.getItem('userInfo')
        try {
            userInfo = JSON.parse(userInfo) || {}
        } catch (err) {
            userInfo = {}
        }
        return <InnerComponent userInfo={userInfo} {...props}></InnerComponent>
    }

    return class OuterComponent extends React.Component {
        constructor() {
            super();
            this.state = {
                userInfo: {}
            }
        }
        componentDidMount() {
            let userInfo = localStorage.getItem('currentUser')
            try {
                userInfo = JSON.parse(userInfo) || {}
            } catch (err) {
                userInfo = {}
            }
            this.setState({
                userInfo
            })
        }
        render() {
            const { userInfo } = this.state;
            return <InnerComponent userInfo={userInfo}></InnerComponent>
        }
    }
}

// export function withStorage(key){
//     // hoc才是高阶组件
//     return function hoc(InnerComponent){
//         return function OuterComponent(props){
//             let value = localStorage.getItem(key)
//             try{
//                 value = JSON.parse(value);
//             }catch(err){
//                 value = value
//             }
//             // props[key] = value;
//             const data = {
//                 [key]:value
//             }
//             // data[key] = value;
//             return <InnerComponent {...data} {...props}></InnerComponent>
//         }
//     }
// }

// 增强版withStorage
export function withStorage(...keys) {

    // hoc才是高阶组件
    return function hoc(InnerComponent) {
        return function OuterComponent(props) {
            const data = {
            }
            keys.forEach(key => {
                let value = localStorage.getItem(key)
                try {
                    value = JSON.parse(value);
                } catch (err) {
                    value = value
                }
                data[key] = value
            })
            return <InnerComponent {...data} {...props}></InnerComponent>
        }
    }
}

// 使用
// withStorage('userInfo',Home);
// 函数柯里化：
// withStorage('userInfo')(Home)
// withStorage('token')(Home)

// 定义高阶组件方式二：反向继承
// 只适用于类组件
export function withAuth(InnerComponent) {
    @withUser
    class OuterComponent extends InnerComponent {
        componentDidMount() {
            super.componentDidMount();
        }
        render() {
            // super: 父类（Mine）
            console.log('OuterComponent.props', this.props)
            return (
                this.props.userInfo.authorization ?
                    super.render()
                    :
                    <Redirect to="/login" />
                // <div>
                //     只有登录后才能访问
                // </div>
            )
        }
    }

    // OuterComponent = withUser(OuterComponent)

    return OuterComponent
}

// 使用属性代理方式实现用户访问权限控制
export function withLogin(InnerComponent) {
    function OuterComponent(props) {
        // 判断用户是否登录
        if (props.userInfo.Authorization) {
            // 校验token有效性（是否过期，是否被篡改）
            // request.get('/admin/verify').then(({ data }) => {
            //     if (data.status === 401) {
            //         props.history.push({
            //             pathname: '/login',
            //             search: 'targetUrl=' + props.location.pathname
            //         })
            //     }
            // })
            return <InnerComponent {...props}></InnerComponent>
        } else {
            return <Redirect to="/login" />
        }
    }

    OuterComponent = withUser(OuterComponent)
    OuterComponent = withRouter(OuterComponent)

    return OuterComponent
}

// withAuth(Mine)

// 共享redux所有属性
export function withRedux(InnerComponent) {

    class OuterComponent extends React.Component {
        state = {
            reduxData: {}
        }
        componentDidMount() {
            let state = store.getState();
            this.setState({
                reduxData: state
            })
            store.subscribe(() => {
                state = store.getState()
                this.setState({
                    reduxData: state
                })
            })
        }
        render() {
            return <InnerComponent {...this.props} {...this.state.reduxData} dispatch={store.dispatch}></InnerComponent>
        }
    }

    return OuterComponent
}

// withRedux(App)
export function withStore(mapStateToProps, mapDispatchToProps) {
    return function hoc(InnerComponent) {
        return class OuterComponent extends React.Component {
            state = {
                data: {},
                methods: {}
            }
            getData() {
                const state = store.getState()
                if(typeof mapStateToProps === 'function'){
                    let data = mapStateToProps(state) || {}
                    this.setState({
                        data,
                    })
                }

                // methods必须包含一个默认的dispatch
                let methods = { dispatch: store.dispatch }
                if(typeof mapDispatchToProps === 'function'){
                    methods = mapDispatchToProps(store.dispatch)
                    
                }

                this.setState({
                    methods
                })
            }
            componentDidMount() {
                this.getData()

                // redux数据更新时
                store.subscribe(() => {
                    this.getData()
                })
            }
            render() {
                const { data, methods } = this.state;
                return <InnerComponent {...data} {...methods} {...this.props}></InnerComponent>
            }
        }
    }
}

// withStore(function(state){
//     // 定义共享的数据
//     return {
//         a:10,
//         user:state.userInfo
//     }
// },function(dispatch){
//     // 定义共享的方法
//     return {
//         login(values){
//             dispatch({
//                 type:'login',
//                 payload:values
//             })
//         }
//     }
// })(App)

// // App组件中的代码
// props.login({username,password})
// props.dispatch({
//     type:'login',
//     payload:{username,password}
// })